#include <assert.h>
#include <mem.h>
#include "list.h"
#include "list_cir.h"
#include "list_link.h"

list* lt_create( CONTAINER_TYPE _ty)
{
	list *_lt = NULL;
	void *_storage = NULL;
	switch ( _ty )
	{
	case CT_LIST_CIR:
		_storage = (void*) ltc_create();
		break;
	case CT_LIST_LINK:
		_storage = (void*) ltl_create();
		break;
	}
	if( _storage != NULL )
	{
		_lt = (list*) palloc( sizeof( list ) );
		assert( _lt != NULL );

		_lt->container = _storage;
		_lt->type = _ty;
	}
	return _lt;
}

void lt_destroy( list* _lt )
{
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		ltc_destroy( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		ltl_destroy( (list_link*)_lt->container );
		break;
	}
	pfree( _lt );
}

int32 lt_size( list* _lt )
{
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		return ltc_size( (list_cir*) _lt->container );
	case CT_LIST_LINK:
		return ltl_size( (list_link*)_lt->container );
	}
	return -1;
}

void lt_pushb( list* _lt, void* _val )
{
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		ltc_pushb( (list_cir*)_lt->container, _val );
		break;
	case CT_LIST_LINK:
		ltl_pushb( (list_link*)_lt->container, _val );
		break;
	}
}

void lt_pushf( list *_lt, void *_val )
{
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		ltc_pushf( (list_cir*)_lt->container, _val );
		break;
	case CT_LIST_LINK:
		ltl_pushf( (list_link*)_lt->container, _val );
		break;
	}
}

list_iterator lt_insert( list_iterator _it, void *_val )
{
	list_iterator it;
	list *_lt;
	_lt = _it.p;
	it.p = _lt;
	it.it = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		it.it = ltc_insert( (list_cir*)_lt->container, (ltc_iterator)_it.it, _val );
		break;
	case CT_LIST_LINK:
		it.it = ltl_insert( (list_link*)_lt->container, (ltl_iterator)_it.it, _val );
		break;
	}
	return it;
}

list_iterator lt_insertp( list *_lt, int32 _pos, void *_val )
{
	list_iterator it;
	it.p = _lt;
	it.it = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		it.it = ltc_insertp( (list_cir*)_lt->container, _pos, _val );
		break;
	case CT_LIST_LINK:
		it.it = ltl_insertp( (list_link*)_lt->container, _pos, _val );
		break;
	}
	return it;
}

void* lt_val( list_iterator _it )
{
	void *_val = NULL;
	switch( _it.p->type )
	{
	case CT_LIST_CIR:
		_val = ltc_val( (ltc_iterator)_it.it );
		break;
	case CT_LIST_LINK:
		_val = ltl_val( (ltl_iterator)_it.it );
		break;
	}
	return _val;
}

void* lt_get( list *_lt, int32 _pos )
{
	void *_val = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_get( (list_cir*)_lt->container, _pos );
		break;
	case CT_LIST_LINK:
		_val = ltl_get( (list_link*)_lt->container, _pos );
		break;
	}
	return _val;
}

void* lt_front( list *_lt )
{
	void *_val = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_front( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		_val = ltl_front( (list_link*)_lt->container );
		break;
	}
	return _val;
}

void* lt_back( list *_lt )
{
	void *_val;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_back( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		_val = ltl_back( (list_link*)_lt->container );
		break;
	}
	return _val;
}

list_iterator lt_begin( list *_lt )
{
	list_iterator it;
	it.p = _lt;
	it.it = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		it.it = ltc_begin( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		it.it = ltl_begin( (list_link*)_lt->container );
		break;
	}
	return it;
}

list_iterator lt_end( list *_lt )
{
	list_iterator it;
	it.p = _lt;
	it.it = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		it.it = ltc_end( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		it.it = ltl_end( (list_link*)_lt->container );
		break;
	}
	return it;
}

list_iterator lt_next( list_iterator _it )
{
	list *_lt = _it.p;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_it.it = ltc_next( (ltc_iterator)_it.it );
		break;
	case CT_LIST_LINK:
		_it.it = ltl_next( (ltl_iterator)_it.it );
		break;
	}
	return _it;
}

list_iterator lt_pre( list_iterator _it )
{
	list *_lt = _it.p;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_it.it = ltc_pre( (ltc_iterator)_it.it );
		break;
	case CT_LIST_LINK:
		_it.it = ltl_pre( (ltl_iterator)_it.it );
		break;
	}
	return _it;
}

list_iterator lt_find( list *_lt, void *_key, compare _fun )
{
	list_iterator it;
	it.p = _lt;
	it.it = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		it.it = ltc_find( (list_cir*)_lt->container, _key, _fun );
		break;
	case CT_LIST_LINK:
		it.it = ltl_find( (list_link*)_lt->container, _key, _fun );
		break;
	}
	return it;
}

void* lt_popf( list* _lt )
{
	void *_val = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_popf( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		_val = ltl_popf( (list_link*)_lt->container );
		break;
	}
	return _val;
}

void* lt_popb( list *_lt )
{
	void *_val = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_popb( (list_cir*)_lt->container );
		break;
	case CT_LIST_LINK:
		_val = ltl_popb( (list_link*)_lt->container );
		break;
	}
	return _val;
}

void* lt_remove( list *_lt, list_iterator _it )
{
	void *_val = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_remove( (list_cir*)_lt->container, (ltc_iterator)_it.it );
		break;
	case CT_LIST_LINK:
		_val = ltl_remove( (list_link*)_lt->container, (ltl_iterator)_it.it );
		break;
	}
	return _val;
}

void* lt_removep( list *_lt, int32 _pos )
{
	void *_val = NULL;
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		_val = ltc_removep( (list_cir*)_lt->container, _pos );
		break;
	case CT_LIST_LINK:
		_val = ltl_removep( (list_link*)_lt->container, _pos );
		break;
	}
	return _val;
}

void lt_sort( list *_lt, compare _fun )
{
	switch( _lt->type )
	{
	case CT_LIST_CIR:
		ltc_sort( (list_cir*)_lt->container, _fun );
		break;
	case CT_LIST_LINK:
		ltl_sort( (list_link*)_lt->container, _fun );
		break;
	}
}
